home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swaga_c.zip / CMDLINE.SWG / 0005_Parse Command Line.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  32KB  |  828 lines

  1. {*************************************************************************)
  2.             Program name: Command parse sub routines
  3.                   Author: Kenneth W. Fox
  4.                           1449 Maple Rd.
  5.                           KintnersVille Pa. 18930
  6.                           USA
  7.            Date Started : 5 AUG 1992
  8.            Date finished: 10 jan 1993
  9.            date last Rev: 20 JAn 1993
  10. *************************************************************************
  11.  
  12. Commandline args:
  13. -----------------
  14. NONE
  15.  
  16. Description of Program:
  17. -----------------------
  18. set of  Procedures to handle all commandline Parameters With or without regard
  19. to Case -- selected by the Boolean Var Nocase -- if True then  everrything
  20. is converted to uppercase prior to testing
  21.  
  22. all arguments returned from switches are left in whatever Case they were
  23. entered on the commandline unless ConvertArgsToUpper is set to True.
  24.  
  25. Includes following Procedures:
  26.  
  27. Procedure NAME          : PURPOSE
  28. ------------------------:-------------------------------------------------
  29.  FnameCheck             : to validate Program name
  30.                           stops people from renanming the Program  if you don't
  31.                           want them to -- if you don't care then don't call
  32.                           this routine.
  33.  
  34.  DispCmdline            : use to display commandline parameters when debugging
  35.  
  36.  ConvertArgtoNumber     : converts specified arg from a String to a numeric
  37.                           value.
  38.  
  39.  CheckHelp              : routine to check to see if the Strings designated
  40.                           as commandline help Strings are present or not.
  41.                           the use of this routine requires the File
  42.                           Helpuser.pas. Additionally this routine checks to
  43.                           see if the 'info' switch was present -- conveniaet
  44.                           way to display registration info in share ware..
  45.  
  46.  
  47.  CmdParse               : main routine to parse command line-- this Procedure
  48.                           is called With Various arguments to alter the content
  49.                           of the CmdArray data structure.
  50.  
  51.  
  52.  
  53. Additonal mods to be made:
  54. ---------------------------
  55. 1) add subroutine in cmdline parser to capture delimited Strings (such as
  56. those between quotes)
  57.  
  58. 2) add subroutine to check if any items one the commandline besides the valid
  59. switches and such were present --
  60.  
  61. to be used For spotting invalid commandline parameters return value should
  62. be Boolean invalid and the paramString(#)...
  63.  
  64. NOTES: may run into trouble writing the routine when the delimited Strings
  65. Function  is added.. possible errors include capturing elements of the
  66. delimited String as invalid args -- will also check For no closing delimiter..
  67.  
  68. 3) develop a version of the cmd line parser which Uses a linked list instead
  69. of a set of Arrays to save the values in -- will save some memory..
  70.  
  71. 4) convert the whole Procedure to an itelligent macro which merely requires
  72. a list of the command args (doesn't use a fixed Array size -- will
  73. dynamically allocate space based on number of arguments specified in the
  74. arg pickup header File. regrettably , some form of header File will need
  75. to be used in order to specify what will be searched For --
  76.  
  77. 5) a possible solution is a way to make a mini compiler macro which will
  78. read in the switches to be processed from a File along With definitions
  79.  
  80. eventually convert the whole thing into a Unit // overlay .
  81.  
  82.  
  83. Rev History:
  84. ------------
  85.  
  86. notes on errors -- if  the switch Strings are not Varying their length
  87.  when Const SwitchLength is changed, then the $I CmdParse.H File is not
  88. in the correct path
  89.  
  90.  remember that the commandArray initialization Procedure is in the
  91. CmdParse.h File and the appropriate adjustments to the qty and values of
  92. the switches need to be made there .. if you are experiencing problems
  93.  With the capture of switches, ensure that you ahe init'd you Array values
  94. correctly
  95.  
  96.  added Boolean present field For argdsw Array
  97.  
  98. 9/5/92 -- moved the call to initCmdArray from the calling routine into the
  99.           initialization section of cmdparse.pas -- because i forgot to add
  100.           it to chkLabel.pas and was going nuts tring to find the error.
  101.           live and learn.
  102.  
  103. 9/5/92 -- added the DispCmdline Procedure as a result of the above session
  104.           of psychosis..
  105.  
  106. 9/6/92 -- re organized cmdparse.pas into more subroutines -- made it easier
  107.           to follow what was going on.. also added removeable code to
  108.           implement a delimited String parser.. this routine will need to
  109.           access the commandline directly instead of using the ParamStr()
  110. (99 min left), (H)elp, More?           Function of turbo.
  111.  
  112. 9/6/92 -- added the ConvertArgtoNumber  routine
  113.           **** NOTE ***** "HelpUser" is a Procedure I add to all Programs
  114.           which use command line args or otherwise -- I normally use an
  115.           $I IncludeFile to implement it.. the Include Staement MUST
  116.           occur BEFORE the include StaTement For CmdParse.pas File..  or
  117.           you can delete the reference to the File from the Program
  118.  
  119. 9/6/92 -- added the standard help codes to the switches Array in cmdParse.H
  120.           ( /? , /h , /H , help , HELP ).
  121.  
  122. 9/6/92 -- added FnameCheck to this File-- FnameCheck requires a Constant or
  123.           String called "ProgName" containing the name of the MAIN Program
  124.           it checks the ParamStr(0) to verify that the Filename of the
  125.           Program has not been renamed -- useful For copyright purposes,
  126.           annoying to users.. use at own peril
  127.  
  128. 9/6/92 -- updated header File to list Procedures avail in cmdparse.pas
  129.  
  130. 1/8/93 -- added the info switch to and DisplayInfo routines to show
  131.           registration / info request address.
  132.  
  133.  
  134. end desc.
  135. }
  136.  
  137. {HEADER File For cmdparse.pas -- include in Calling File   }
  138.  
  139. {PROGNAME.pas}  {<<<<----- Program using this header File   }
  140. { 20 Jan 1993} {<<<<----- date this File last changed      }
  141. { Ken Fox    }  {<<<<----- Person who last updated this File}
  142.  
  143. (*
  144. Uses Dos,Crt;
  145.  
  146. Const
  147.   VersionNum = 'V1.0 BETA';
  148.   ProgNameStr = 'NEWPROJ.EXE';
  149.   ProgNameShortStr = 'NP.EXE';
  150.   copyRightStr = ProgNameStr+' ' + VersionNum +
  151.                 ', Copyright 1992 - 1993, Ken Fox. All Rights Reserved.';
  152.  
  153.   DefaultFileName = 'NEWPROJ.DAT';
  154.  
  155. *)
  156.  
  157. {--------------------------------------------------------------------------}
  158. {                          procs Available in CmdParse.H                   }
  159. { Procedure   initCmdArray(Var CmdArray : CommandLineArrayType);           }
  160. {   this proc is included in ths File becuase the args to check For are    }
  161. { part of the calling routine, not the parser itself. note that the excess }
  162. { switches are commented out and will there For not compile but it will    }
  163. { make it easier to add stuff in the future should you so desire           }
  164. {--------------------------------------------------------------------------}
  165. {                          procs Available in CmdParse.Pas                 }
  166. { additional info on the following procs may be found in the cmdparse.Pas  }
  167. { File in the ....\tp\include directory..                                  }
  168. {                                                                          }
  169. { Procedure DispCmdline;                                                   }
  170. {                                                                          }
  171. { Procedure CmdParse(Var CmdArray : CommandLineArrayType;                  }
  172. {                            NoCase,                                       }
  173. {                            ConvertArgsToUpper   : Boolean );             }
  174. {                                                                          }
  175. { Procedure ConvertArgtoNumber(ArgNum : Integer;                           }
  176. {                             Var  CmdArray : CommandLineArrayType;        }
  177. {                             Var  ResultNumber: Word);                    }
  178. {                                                                          }
  179. { Procedure FnameCheck(progname , progname2 :pathStr;                      }
  180. {                      errorlevel : Byte);                                 }
  181. {                                                                          }
  182. { Procedure CheckHelp;                                                     }
  183. {                                                                          }
  184. {--------------------------------------------------------------------------}
  185.  
  186. Const
  187. SwitchLength = 4;   {   maxlegth of a switch to be tested for}
  188. ArgLength = 11;     {   max length of an argument from the commandline}
  189. DelimLength = 1;     {   maxlength of delimiter if used}
  190. SwitchNum = 6;      {   the number of switches and hence the size of the Array}
  191.                     {      of switches  without arguments                  }
  192. ArgdSwitchNum = 2;  {   the number of switches and hence the size of the Array}
  193.                     {      of switches  With arguments                 }
  194. DelimNum = 1;       {   number of args With delimited Strings          }
  195.  
  196.  
  197. Type
  198. SwitchType = String[Switchlength];
  199. ArgType = String[ArgLength];
  200. DelimType = String[DelimLength];
  201.  
  202. SwitchesType = Record
  203.          Switch : Array[1..SwitchNum] of SwitchType;
  204.          Present : Array[1..switchNum] of Boolean
  205.          end;
  206.  
  207. SwitchWithArgType = Record
  208.               Switch  : Array[1..ArgdSwitchNum] Of SwitchType;
  209.               Arg     : Array[1..ArgdSwitchNum] Of ArgType;
  210.               Present : Array[1..ArgdSwitchNum] of Boolean
  211.               end;
  212.  
  213. SwitchedArgWithEmbeddedSpacesType = Record
  214.               Switch     : Array[1..DelimNum] Of SwitchType;
  215.               StartDelim : Array[1..DelimNum] of DelimType;
  216.               Arg        : Array[1..DelimNum] Of ArgType;
  217.               endDelim   : Array[1..DelimNum] of DelimType;
  218.               Present    : Array[1..DelimNum] of Boolean
  219.               end;
  220.  
  221.  
  222. CommandLineArrayType = Record
  223.            Switches : SwitchesType;
  224.            ArgDSw   : SwitchWithArgType;
  225.            {    DelimSw  : SwitchedArgWithEmbeddedSpacesType; }
  226.            NoParams : Boolean           {True if nothing on commandline}
  227.            end;
  228.  
  229. Var
  230. NoCase,
  231. ConvertArgsToUpper
  232.                   : Boolean;
  233.  
  234. CmdArray                : CommandLineArrayType;
  235.  
  236. Procedure   initCmdArray(Var CmdArray : CommandLineArrayType);
  237.  
  238. begin
  239.    {DEFAULT VALUES SET}
  240.    NoCase := True;
  241.    ConvertArgsToUpper := True;
  242.  
  243. with CmdArray do
  244.    begin
  245.    Switches.Switch[1] := '/?' ;     {default help String}
  246.    Switches.Switch[2] := '/h' ;     {default help String}
  247.    Switches.Switch[3] := '/H' ;     {default help String}
  248.    Switches.Switch[4] := 'HELP' ;   {default help String}
  249.    Switches.Switch[5] := 'help' ;   {default help String}
  250.    Switches.Switch[6] := 'INFO'     {show author contact Info}
  251.  
  252. {   Switches.Switch[6] := '  ' ;}   {NOT USED}
  253. {   Switches.Switch[7] := '  ' ;}   {NOT USED}
  254. {   Switches.Switch[8] := '  ' ;}   {NOT USED}
  255. {   Switches.Switch[9] := '  ' ;}   {NOT USED}
  256. {   Switches.Switch[10] := '  ' ;}  {NOT USED}
  257. {   Switches.Switch[11] := '  ' ;}  {NOT USED}
  258. {   Switches.Switch[12] := '  ' ;}  {NOT USED}
  259.  
  260. {  ArgDSw.Switch[1] := '' ;}       {not used}
  261. {  ArgDSw.Switch[2] := '' ;}       {not used}
  262. {  ArgDSw.Switch[3] := '' ;}       {NOT USED}
  263. {  ArgDSw.Switch[4] := '' ;}       {NOT USED}
  264. {  ArgDSw.Switch[5] := '' ;}       {NOT USED}
  265. {  ArgDSw.Switch[6] := '' ;}       {NOT USED}
  266. {  ArgDSw.Switch[7] := '' ;}       {NOT USED}
  267. {  ArgDSw.Switch[8] := '' ;}       {NOT USED}
  268. {  ArgDSw.Switch[9] := '' ;}       {NOT USED}
  269. {  ArgDSw.Switch[10] := '' ;}      {NOT USED}
  270. {  ArgDSw.Switch[11] := '' ;}      {NOT USED}
  271. {  ArgDSw.Switch[12] := '' ;}      {NOT USED}
  272. {  ArgDSw.Switch[13] := '' ;}      {NOT USED}
  273. (*
  274. With DelimSw Do
  275. {     Switch[1]     := '' ;     }  {NOT USED}
  276. {     StartDelim[1] := '' ;     }  {NOT USED}
  277. {     endDelim[1]   := '' ;     }  {NOT USED}
  278. {     Switch[2] := '' ;         }  {NOT USED}
  279. {     StartDelim[2] := '' ;     }  {NOT USED}
  280. {     endDelim[2]   := '' ;     }  {NOT USED}
  281.  
  282. {     Switch[3] := '' ;         }  {NOT USED}
  283. {     StartDelim[3] := '' ;     }  {NOT USED}
  284. {     endDelim[3]   := '' ;     }  {NOT USED}
  285.  
  286. {     Switch[4] := '' ;         }  {NOT USED}
  287. {     StartDelim[4] := '' ;     }  {NOT USED}
  288. {     endDelim[4]   := '' ;     }  {NOT USED}
  289.  
  290. {     Switch[5] := '' ;         }  {NOT USED}
  291. {     StartDelim[5] := '' ;     }  {NOT USED}
  292. {     endDelim[5]   := '' ;     }  {NOT USED}
  293.  
  294. {     Switch[6] := '' ;         }  {NOT USED}
  295. {     StartDelim[6] := '' ;     }  {NOT USED}
  296. {     endDelim[6]   := '' ;     }  {NOT USED}
  297.  
  298. {     Switch[7] := '' ;         }  {NOT USED}
  299. {     StartDelim[7] := '' ;     }  {NOT USED}
  300. {     endDelim[7]   := '' ;     }  {NOT USED}
  301.  
  302. {     Switch[8] := '' ;         }  {NOT USED}
  303. {     StartDelim[8] := '' ;     }  {NOT USED}
  304. {     endDelim[8]   := '' ;     }  {NOT USED}
  305.  
  306. {     Switch[9] := '' ;         }  {NOT USED}
  307. {     StartDelim[9] := '' ;     }  {NOT USED}
  308. {     endDelim[9]   := '' ;     }  {NOT USED}
  309.  
  310. {     Switch[10] := '' ;        }  {NOT USED}
  311. {     StartDelim[10] := '' ;    }  {NOT USED}
  312. {     endDelim[10]   := '' ;    }  {NOT USED}
  313.  
  314. {     Switch[11] := '' ;        }  {NOT USED}
  315. {     StartDelim[11] := '' ;    }  {NOT USED}
  316. {     endDelim[11]   := '' ;    }  {NOT USED}
  317. (99 min left), (H)elp, More? 
  318. {     Switch[12] := '' ;        }  {NOT USED}
  319. {     StartDelim[12] := '' ;    }  {NOT USED}
  320. {     endDelim[12]   := '' ;    }  {NOT USED}
  321.  
  322. {     Switch[13] := '' ;        }  {NOT USED}
  323. {     StartDelim[13] := '' ;    }  {NOT USED}
  324. {     endDelim[13]   := '' ;    }  {NOT USED}
  325.  
  326. {     Switch[14] := '' ;        }  {NOT USED}
  327. {     StartDelim[14] := '' ;    }  {NOT USED}
  328. {     endDelim[14]   := '' ;    }  {NOT USED}
  329. end {with DelimSw }
  330. *)
  331. end; {WITH CmdArray}
  332.  
  333. end;
  334.  
  335. Procedure CmdParse(Var CmdArray : CommandLineArrayType;
  336.                              NoCase,
  337.                              ConvertArgsToUpper   : Boolean );
  338.  
  339. { Procedure to handle all commandline Parameters With or without regard }
  340. {to Case -- selected by the Boolean Var Nocase -- if True then  everrything}
  341. {is converted to uppercase prior to testing}
  342.  
  343. {all arguments returned from switches are left in whatever Case they were }
  344. {entered on the commandline unless ConvertArgsToUpper is set to True.}
  345.  
  346. Const
  347.    Blank = ' ';
  348.  
  349. Var
  350.    counter                 : Integer;
  351.    Blanks                  : ArgType;
  352.  
  353. {+++++++++++++++++++++++  Private Procedures to CmdParse Main  +++++++++++++}
  354. Procedure ConvertArgsToUpperCase(Var CmdArray:CommandLineArrayType);
  355. Var
  356.   Counter,
  357.   Counter2   : Integer;
  358. begin   {--------->>>> ConvertArgsToUpperCase <<<<------------}
  359.  
  360.   For Counter := 1 to ArgDSwitchNum Do
  361.       For Counter2 := 1 to Length(CmdArray.ArgDSw.Arg[counter]) DO
  362.           CmdArray.ArgDSw.Arg[counter,Counter2] :=
  363.                 UPCASE(CmdArray.ArgDSw.Arg[counter,Counter2] );
  364.  
  365. end;    {--------->>>> ConvertArgsToUpperCase <<<<------------}
  366.  
  367. {----------------------------------------------------------------------}
  368. Procedure ConvertSwitchesToUpperCase(Var CmdArray:CommandLineArrayType);
  369. Var
  370.   Counter,
  371.   Counter2   : Integer;
  372.  
  373. begin  {--------->>>> ConvertSwitchesToUpperCase  <<<<------------}
  374.    For Counter := 1 to SwitchNum Do
  375.       begin
  376.       For Counter2 := 1 to Length(CmdArray.Switches.Switch[counter]) DO
  377.           CmdArray.Switches.Switch[counter,Counter2] :=
  378.              UPCASE(CmdArray.Switches.Switch[counter,Counter2]);
  379.       end;
  380.    For Counter := 1 to ArgDSwitchNum Do
  381.       For Counter2 := 1 to Length(CmdArray.ArgDSw.Switch[counter]) DO
  382.           CmdArray.ArgDSw.Switch[counter,Counter2] :=
  383.                 UPCASE(CmdArray.ArgDSw.Switch[counter,Counter2] );
  384.  
  385. end;  {--------->>>> ConvertSwitchesToUpperCase  <<<<------------}
  386.  
  387. {----------------------------------------------------------------------}
  388.  
  389. Procedure InitializeArrays(Var CmdArray:CommandLineArrayType;
  390.                            Var Nocase : Boolean  );
  391. Var
  392.    Counter
  393.           : Integer;
  394.  
  395. begin     {--------->>>> InitializeArrays  <<<<------------}
  396.  
  397.   cmdArray.NoParams := False;
  398.   For Counter := 1 to SwitchNum Do
  399.     CmdArray.Switches.present[counter] := False;
  400.   For Counter := 1 to ArgDSwitchNum Do
  401.     begin
  402.        CmdArray.ArgDSw.present[counter] := False;
  403.        CmdArray.ArgDSw.Arg[counter] := Blanks;
  404.     end;
  405.   if NoCase then                           {convert all Switches in CmdArray}
  406.      ConvertSwitchesToUpperCase(CmdArray); {to uppercaseif nocase is set to }
  407.                                            {True}
  408. end;       {--------->>>> InitializeArrays  <<<<------------}
  409. {----------------------------------------------------------------------}
  410. Procedure ParseNow(Var CmdArray:CommandLineArrayType;
  411.                            Var Nocase : Boolean  );
  412. Var
  413. Counter,Counter2,
  414. Start,
  415. SwitLen,CurrentArgLen   : Integer;
  416. Blanks                  : ArgType;
  417. TestStr                 : SwitchType;
  418. WorkStr                 : String;
  419.  
  420. Label
  421.    Next_Parameter;
  422.  
  423. begin   {--------->>>> ParseNow <<<<------------}
  424.   {check For switches without args first}
  425.  
  426.   For counter := 1 to ParamCount Do
  427.     begin  {number of Parameters Loop}
  428.        TestStr:= ParamStr(counter);
  429.  
  430.        if Nocase Then    { covert paramStr(counter) to upper Case if NoCase}
  431.           begin          { is set to True}
  432.             WorkStr := TestStr;
  433.             For Counter2 := 1 to SwitchLength DO
  434.                 TestStr[counter2]  := UPCASE((WorkStr[counter2]));
  435.           end;
  436.  
  437.       For Counter2 := 1 to SwitchNum Do
  438.            begin  { Switches without arguments loop }
  439.               SwitLen := Length(CmdArray.Switches.Switch[Counter2]);
  440.               if CmdArray.Switches.Switch[Counter2] =
  441.                     Copy(TestStr,1,SwitLen) then
  442.  
  443.                     begin
  444.                        CmdArray.Switches.Present[Counter2] := True;
  445.                        Goto Next_Parameter;
  446.                      end;
  447.            end; { Switches without arguments loop }
  448.  
  449.        For counter2 := 1 to ArgDSwitchNum  Do
  450.            begin     { Switches With arguments test loop }
  451.  
  452.               SwitLen := Length(CmdArray.ArgDSw.Switch[Counter2]);
  453.               if CmdArray.ArgDSw.Switch[Counter2] =
  454.                     Copy(TestStr,1,SwitLen) then
  455.  
  456.                  begin
  457.                     CmdArray.ArgDSw.present[Counter2] := True;
  458.                     Start := length(CmdArray.ArgDSw.Switch[Counter2]) + 1;
  459.                     CurrentArgLen := length(paramStr(counter)) - (start-1);
  460.                     CmdArray.ArgDSw.Arg[Counter2] :=
  461.                           Copy(ParamStr(Counter),Start,CurrentArgLen);
  462.  
  463.                     Goto Next_Parameter; {used inplace of an Exit}
  464.                  end;
  465.            end;     { Switches With arguments test loop }
  466.  
  467.     next_parameter:; {used to speed up execution -- Exit doesn't work here}
  468.  
  469.     end;        {number of Parameters Loop}
  470.  
  471. end;    {--------->>>> ParseNow <<<<------------}
  472.  
  473. Procedure Parsedelimited(Var CmdArray : CommandLineArrayType;
  474.                              NoCase,
  475.                              ConvertArgsToUpper   : Boolean );
  476.  
  477. {this Procedure will bag any String on the commandline With embedded spaces}
  478. (*  and is delimited by Characters such as "" , {}, [], (), <>, ^^, etc ...*)
  479.  
  480.  
  481. begin    {--------->>>> Parsedelimited <<<<------------}
  482. end;     {--------->>>> Parsedelimited <<<<------------}
  483. {----------------------------------------------------------------------}
  484.  
  485. {+++++++++++++++++++ end  Private Procedures to CmdParse Main  +++++++++++++}
  486.  
  487. {==================================== MAIN Procedure ===================}
  488. begin           {+++++++++>>>> Procedure CmdParse  <<<<++++++++++++}
  489.   {Init Arrays}
  490.   For counter := 1 to ArgLength do      {  the String Blanks needs to be }
  491.       Blanks[Counter] := Blank;         {  global because most routines  }
  492.                                         {  are useing it                 }
  493.  
  494.   InitCmdArray(CmdArray); { this Procedure located in the cmdparse.h File}
  495.                           { assigns values to switches, etc.}
  496.  
  497.   InitializeArrays(CmdArray,NoCase);
  498.  
  499.  
  500.  
  501.   If ParamCount = 0 then                { check command line For null String}
  502.      begin                              { if nullString then set No Params  }
  503.         cmdArray.NoParams := True;      { and return to the calling routine }
  504.         Exit;
  505.      end;
  506.  
  507.  
  508.    ParseNow(CmdArray, Nocase);           { routine parses the commandline   }
  509.                                          { passing through the switches w/o }
  510.                                          { arguments first. When Delimited  }
  511.  { If Not(NoDelimited) then }            { switch parsing is added, it will }
  512.    { Parsedelimited(CmdArray,NoCase);}   { occur after all other parsing    }
  513.                                          { as a seperate routine to follow  }
  514.                                          { PARSENOW -- additionally -- add  }
  515.                                          { Boolean Value "NoDelimited" to   }
  516.                                          { calling routine and Cmdparse.h   }
  517.                                          { to bypass checking For delimited }
  518.  
  519.   if ConvertArgsToUpper then
  520.        ConvertArgsToUpperCase(CmdArray);
  521.  
  522.  
  523. end;     {+++++++++>>>> Procedure CmdParse  <<<<++++++++++++}
  524.  
  525. {======================  end CmdParse MAIN Procedure ===================}
  526.  
  527. { /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  528. {                    Parser Utility routines                            }
  529. { /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  530.  
  531. Procedure ConvertArgtoNumber(ArgNum : Integer;
  532.                              Var  CmdArray : CommandLineArrayType;
  533.                              Var  ResultNumber: Word);
  534. Var
  535.   code : Integer;
  536.  
  537. begin    {----------->>>> ConvertArgtoNumber <<<<---------------}
  538.  
  539.   Val(CmdArray.ArgDsw.Arg[ArgNum],ResultNumber,code);
  540.     if code <> 0 then
  541.        begin
  542.           WriteLn('Error commandline argument: ',
  543.                        CmdArray.ArgDsw.Switch[ArgNum],'  ',
  544.                        CmdArray.ArgDsw.Arg[ArgNum]);
  545.           Writeln('press enter to continue');
  546.           readln;
  547.           HelpUser;  {see notes}
  548.        end;
  549.  
  550. end;     {----------->>>> ConvertArgtoNumber <<<<---------------}
  551.  
  552. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  553.  
  554. Procedure FnameCheck(progname, progname2 :pathStr;
  555.                      errorlevel : Byte);
  556. Var
  557. teststr1,teststr2 :pathStr;
  558.  
  559. begin    {----------->>>> FnameCheck <<<<---------------}
  560.  
  561. teststr1 := copy(paramstr(0),(length(paramstr(0)) - (Length(progname)-1) ),
  562.                              Length(progname));
  563. teststr2 := copy(paramstr(0),(length(paramstr(0)) - (Length(progname2)-1) ),
  564.                              Length(progname2));
  565.  
  566. if ((teststr1 <> ProgName) and (teststr2 <> ProgName2))
  567.    then
  568.      begin
  569.      WriteLn('Unrecoverable Error in ',progname, ', Check FileNAME');
  570.      halt(Errorlevel);
  571.      end;
  572.  
  573. end;     {----------->>>> FnameCheck <<<<---------------}
  574.  
  575. {/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\}
  576.  
  577. Procedure DispCmdline;
  578.      { use For debugging -- displays the command line parameters}
  579.      { readln at end shows screen Until enter is pressed}
  580. VAr Count : Integer;
  581. begin
  582. ClrScr;
  583.  
  584. For Count := 1 to  SwitchNum do
  585.     if CmdArray.Switches.present[count] then
  586.        WriteLn(CmdArray.Switches.Switch[count],'    Present');
  587.  
  588. For Count := 1 to ArgdSwitchNum  do
  589.     if CmdArray.ArgDsw.present[count] then
  590.        begin
  591.           WriteLn(CmdArray.ArgDsw.Switch[count],'   Present.');
  592.           WriteLn('Value of:  ',CmdArray.ArgDsw.Arg[count]);
  593.        end;
  594.  
  595. Writeln;
  596. Write('press ENTER to continue');
  597. ReadLn;
  598. Halt(0);
  599. end;
  600.  
  601. Procedure CheckHelp;
  602. Var
  603.    COUNT : Byte;
  604. begin
  605.    For count := 1 to 5 do
  606.      if cmdArray.Switches.Present[Count] then
  607.         helpUser;
  608.  
  609.    if cmdArray.Switches.Present[6] then
  610.      displayinfo;
  611. end;
  612.  
  613. {---------------------------Helpuser --------------------------}
  614. Procedure HelpUser;
  615. begin
  616.    ClrScr;
  617.    Writeln (CopyRightStr);
  618.    WriteLn;
  619.    WriteLn('USAGE: ');
  620.    WriteLn;
  621.    WriteLn;
  622.    WriteLn;
  623.    WriteLn;
  624.    WriteLn;
  625.    WriteLn;
  626.    WriteLn;
  627.    WriteLn;
  628.    WriteLn;
  629.    WriteLn;
  630.    WriteLn;
  631.    WriteLn;
  632.    WriteLn;
  633.    WriteLn;
  634.    WriteLn;
  635.    WriteLn;
  636.    WriteLn;
  637.    WriteLn;
  638.    Writeln;
  639.    Writeln('Press Enter to continue.');
  640.    ReadLn;
  641.    Writeln;
  642.    WriteLn('EXAMPLE:...............................');
  643.    WriteLn;
  644.    WriteLn;
  645.    WriteLn;
  646.    WriteLn;
  647.    WriteLn;
  648.    WriteLn;
  649.    WriteLn;
  650.    WriteLn;
  651.    WriteLn;
  652.    WriteLn;
  653.    WriteLn;
  654.    WriteLn;
  655.    WriteLn;
  656.    WriteLn;
  657.    WriteLn;
  658.    WriteLn;
  659.    WriteLn;
  660.    WriteLn;
  661.    WriteLn;
  662.    WriteLn;
  663.    WriteLn;
  664.    WriteLn;
  665.    WriteLn;
  666.    Writeln (CopyRightStr);
  667.    halt(0);
  668.  end;
  669. {-------------------------------------------------------------------------}
  670. Procedure DisplayInfo;
  671.    begin
  672.       ClrScr;
  673.       Writeln(copyrightStr);
  674.       Writeln;
  675.       Writeln('Ken Fox');
  676.       WriteLn('1449 Maple Rd.');
  677.       Writeln('Kintnersville Pa. 18930');
  678.       WriteLn('215 672-9713       9 - 5 EST');
  679.       Writeln;
  680.       Writeln('Contact on shareware conference on Internet  -- KEN FOX');
  681.       Writeln;
  682.       halt(0);
  683.  
  684.    end;
  685. {--------------------------------------------------------------------------}
  686.  
  687. this info is For all of the PASCAL conference people:
  688.  
  689. to use the rotuines in this Program you need to do the following
  690.  
  691. {$I path.......\Progname.h}
  692. {$I Path.......\Helpuser.PAS}
  693. {$I path.......\CMDPARSE.PAS}
  694.  
  695.  progname.H is a copy of the CMDPARSE.H File which contains the specific
  696.  settings For the Program you are writing .
  697.  
  698.  HELPUSER.PAS is a Program specific help routine which get called by
  699.  the routie CHECKHELP in CMDPARSE.PAS if the CheckHelp Procedure is
  700.  used in the main Program. crude but effective.
  701.  
  702.  CMDPARSE.PAS -- this File contains all of the parsing routines. I keep this
  703.  File in my .....\TP\INCLUDE directory .
  704.  
  705.  I set up a sepearte directory below the tp directory For each Program
  706.  and copy the Files Helpuser.Pas and cmdparse.h into it thusly each
  707.  copy of these two Files is customized For the give application While
  708.  the actual parsing routines are kept in the INCLUDED FileS directory.
  709.  there's no need to modify CMDPARSE.PAS
  710.  
  711.  using the parser..
  712.  
  713.        1) in the CMDPARSE.H File there are templates For all of the Array
  714.  initializations. the switches to search For are manually inserted in to
  715.  each Array item. additionally the Array sizes must be set where indicated
  716.  in the CMDPARSE.H File.
  717. {-------------------------------------------------------------------------}
  718.   THE FOLLOWING ARE THE SETTINGS For Array SIZES
  719. {-------------------------------------------------------------------------}
  720.  
  721. Const
  722. SwitchLength = 4;   {   maxlegth of a switch to be tested for}
  723. ArgLength = 11;     {   max length of an argument from the commandline}
  724. DelimLength = 1;     {   maxlength of delimiter if used}
  725. SwitchNum = 6;      {   the number of switches and hence the size of the Array}
  726.                     {      of switches  without arguments                  }
  727. ArgdSwitchNum = 2;  {   the number of switches and hence the size of the Array}
  728.                     {      of switches  With arguments                 }
  729. DelimNum = 1;       {   number of args With delimited Strings          }
  730.  
  731. {-------------------------------------------------------------------------}
  732.      THE FOLLOWING SHOW HOW to INIT THE Array SEARCH VarIABLES..
  733.      THESE LINES ARE ALL CONTAINED in  ---->>>> CMDPARSE.H
  734. {-------------------------------------------------------------------------}
  735.  
  736.    Switches.Switch[1] := '/?' ;     {default help String}
  737.    Switches.Switch[2] := '/h' ;     {default help String}
  738.    Switches.Switch[3] := '/H' ;     {default help String}
  739.    Switches.Switch[4] := 'HELP' ;   {default help String}
  740.    Switches.Switch[5] := 'help' ;   {default help String}
  741.    Switches.Switch[6] := 'INFO'     {show author contact Info}
  742.  
  743. {   Switches.Switch[6] := '  ' ;}   {NOT USED}
  744.  
  745. {---------------------------------}
  746. THE FOLLOWING ARE For SWITCHES WHICH WILL CAPTURE A VALUE AS WELL AS
  747. TEST For THE PRESENCE of THE ARGUMENT
  748. {---------------------------------}
  749. {  ArgDSw.Switch[1] := '' ;}       {not used}
  750. {  ArgDSw.Switch[2] := '' ;}       {not used}
  751. {  ArgDSw.Switch[3] := '' ;}       {NOT USED}
  752. {  ArgDSw.Switch[4] := '' ;}       {NOT USED}
  753. {  ArgDSw.Switch[5] := '' ;}       {NOT USED}
  754. {  ArgDSw.Switch[6] := '' ;}       {NOT USED}
  755. {  ArgDSw.Switch[7] := '' ;}       {NOT USED}
  756.  
  757. {-------------------------------------------------------------------------}
  758.  
  759.        2) if you intend to use the routines in HELPUSER.PAS or to perform
  760. a Filename validation  -- there is a template at the beginning of CMDPARSE.H
  761. with Certain Constants which must be set.
  762.  
  763. Uses Dos,Crt;
  764.  
  765. Const
  766.   VersionNum = 'V1.0 BETA';
  767.   ProgNameStr = 'NEWPROJ.EXE';
  768.   ProgNameShortStr = 'NP.EXE';
  769.   copyRightStr = ProgNameStr+' ' + VersionNum +
  770.                 ', Copyright 1992 - 1993, Ken Fox. All Rights Reserved.';
  771.  
  772.   DefaultFileName = 'NEWPROJ.DAT';
  773.  
  774. {-------------------------------------------------------------------------}
  775.  
  776.       3) To call the Various routines in  the CMDPARSE.PAS File there are
  777. Templates which you can cut and paste into you Program from  CMDPARSE.H
  778.  
  779. {--------------------------------------------------------------------------}
  780. {                          procs Available in CmdParse.Pas                 }
  781. { additional info on the following procs may be found in the cmdparse.Pas  }
  782. { File in the ....\tp\include directory..                                  }
  783. {                                                                          }
  784. { Procedure DispCmdline;                                                   }
  785. {                                                                          }
  786. { Procedure CmdParse(Var CmdArray : CommandLineArrayType;                  }
  787. {                            NoCase,                                       }
  788. {                            ConvertArgsToUpper   : Boolean );             }
  789. {                                                                          }
  790. { Procedure ConvertArgtoNumber(ArgNum : Integer;                           }
  791. {                             Var  CmdArray : CommandLineArrayType;        }
  792. {                             Var  ResultNumber: Word);                    }
  793. {                                                                          }
  794. { Procedure FnameCheck(progname , progname2 :pathStr;                      }
  795. {                      errorlevel : Byte);                                 }
  796. {                                                                          }
  797. { Procedure CheckHelp;                                                     }
  798. {                                                                          }
  799. {--------------------------------------------------------------------------}
  800.  
  801.       4) To test whether an ON/OFF switch is present (such as /?) on the
  802. commandline  use the following:
  803.  
  804.              if CmdArray.Switches.Present[number] then
  805.                 begin
  806.                 end;
  807.  
  808.       5) to get the argument from a switch .
  809.  
  810.             if CmdArray.ArgDsw.Present[number] then
  811.                WhatEverVariable := CmdArray.ArgDsw.Arg[number];
  812.  
  813.       6) the Procedure ConvertArgtoNumber is avail to convert a
  814. String on the command line to a decimal number.. this is only good for
  815. for whole numbers w/o nnn.0000111 etc.
  816.  
  817.  
  818. hope this stuff is useful -- there are other notes and comments sprinkled
  819. throughout so please check those before calling..
  820.  
  821. finally - in the interest traversing the command tail only once the most
  822. henious of Programming Constructs -- the Goto statement -- has been used.
  823. please forgive me in advance....
  824.  
  825. questions comments and suggestions are welcome..
  826.  
  827. see the address in the CMDPASE.DOC File..
  828.